package com.wang.common.core.domain;

import com.wang.common.core.enums.ResultCode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

/**
 * 响应数据类型 R<T>
 * @param <T>
 */
@Schema(description = "统一返回结果R")
@Data
public class R<T> {

    @Schema(description = "状态码")
    private int code;

    @Schema(description = "状态信息")
    private String msg;

    @Schema(description = "返回数据 (泛型,不同接口返回的数据类型不同)")
    private T data;

    //操作成功 --> 调用success方法
    //方法重载
    //(1) 不带参数的 success 方法 --> 不返回数据,只返回 成功状态码+信息
     public static <T> R<T> success() {
        return generateR(null, ResultCode.SUCCESS);
    }

    //(2) 带参数的 success 方法 (参数是要返回的数据)--> 返回数据+成功状态码+信息
    public static <T> R<T> success(T data) {
        return generateR(data, ResultCode.SUCCESS);
    }


    //操作失败 --> 调用fail方法
    //方法重载
    //(1) 不带参数的 fail 方法 --> 返回默认失败信息(FAILED)
    public static <T> R<T> fail() {
        return generateR(null, ResultCode.FAILED);
    }

    //(2) 带参数的 fail 方法 --> 返回指定的状态码+信息
    public static <T> R<T> fail(ResultCode resultCode) {
        return generateR(null, resultCode);
    }
    //(3) 带参数的 fail 方法 --> 返回自定义的状态码+信息
    public static <T> R<T> fail(int code, String msg) {
        return generateR(null, code, msg);
    }


    //封装 R 的方法 generateR()
    //方法重载
    //(1) 用已有的状态码和信息
    private static <T> R<T> generateR(T data, ResultCode resultCode) {

        R<T> r = new R<>(); //先创建一个R对象

        r.setData(data);
        r.setCode(resultCode.getCode());
        r.setMsg(resultCode.getMsg());

        return r;
    }

    //(2) 自定义状态码和信息
    private static <T> R<T> generateR(T data, int code, String msg) {

        R<T> r = new R<>();

        r.setData(data);
        r.setCode(code);
        r.setMsg(msg);

        return r;
    }
}
